home *** CD-ROM | disk | FTP | other *** search
- Subject: v15i050: Updated IEN-116 namesever
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Jerry Aguirre <jerry@oliveb.atc.olivetti.com>
- Posting-number: Volume 15, Issue 50
- Archive-name: ien116
-
- [ I used an earlier version in playing with some PC networking code
- at my old job. --r$ ]
-
- This program implements the IEN 116 nameserver protocol. A driver is
- provided, its first argument is the network name of the host running the
- nameserver, arguments 2-n are names to request the IP address of. This
- program is of use primarily for Bridge terminal servers, many of which
- use this protocol in requesting machine addresses. For further
- information, see the document itself.
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # README
- # nameserver.8
- # Makefile
- # ien116.h
- # nameserver.c
- # driver.c
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'README'" '(805 characters)'
- if test -f 'README'
- then
- echo shar: will not over-write existing file "'README'"
- else
- sed 's/^X//' << \SHAR_EOF > 'README'
- XThis program implements the IEN 116 nameserver protocol. A driver is
- Xprovided, its first argument is the network name of the host running the
- Xnameserver, arguments 2-n are names to request the IP address of. This
- Xprogram is of use primarily for Bridge terminal servers, many of which
- Xuse this protocol in requesting machine addresses. For further
- Xinformation, see the document itself.
- X
- XTo compile, the command:
- X % make
- Xis sufficient. This will build the nameserver and the driver. The
- Xcommand:
- X % make install
- Xwill install the nameserver daemon in /etc. Start it by hand initially
- Xand then modify your rc.local file to run it at boot time.
- X
- XIt is only known that this works on a 4.3BSD Vax, but it is likely that
- Xit will function on any compatable UNIX(*) machine.
- X
- X(*) UNIX is a trademark of AT&T.
- SHAR_EOF
- if test 805 -ne "`wc -c < 'README'`"
- then
- echo shar: error transmitting "'README'" '(should have been 805 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'nameserver.8'" '(702 characters)'
- if test -f 'nameserver.8'
- then
- echo shar: will not over-write existing file "'nameserver.8'"
- else
- sed 's/^X//' << \SHAR_EOF > 'nameserver.8'
- X.TH nameserver 8 "Local \- June 24, 1987" "M. I. Bushnell"
- X.SH NAME
- Xnameserver \- process IEN 116 requests
- X.SH SYNOPSIS
- X.B nameserver
- X.SH DESCRIPTION
- X\fBNameserver\fR processes requests for network addresses using the IEN 116
- Xprotocol.
- X.SH SEE ALSO
- XIEN 116 \- Internet Name Server (J. Postel)
- X.SH DIAGNOSTICS
- XVarious messages logged by syslog using LOG_CRIT and LOG_ERR.
- XMainly self-explanatory. Errors such as
- X.RS .5i
- XError sending error \fIn\fR: ....
- X.RE
- Xrefer to errors in the transmission of error messages back to the requestor.
- XFor explanation of the numbers, see the source.
- X.SH BUGS
- XWill not properly detach from the terminal if the terminal is opened on
- Xany descriptor other than 0, 1, or 2.
- SHAR_EOF
- if test 702 -ne "`wc -c < 'nameserver.8'`"
- then
- echo shar: error transmitting "'nameserver.8'" '(should have been 702 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'Makefile'" '(352 characters)'
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- sed 's/^X//' << \SHAR_EOF > 'Makefile'
- X# Makefile for the IEN116 datagram server.
- X
- XCFLAGS=-O
- X
- Xall: nameserver driver
- X
- Xnameserver: nameserver.c
- X $(CC) $(CFLAGS) -o nameserver nameserver.c
- X
- Xdriver: driver.c
- X $(CC) $(CFLAGS) -o driver driver.c
- X
- X# installer needs write access to /etc/nameserver (root)
- Xinstall: /etc/nameserver
- X/etc/nameserver: nameserver
- X install -c nameserver /etc/nameserver
- SHAR_EOF
- if test 352 -ne "`wc -c < 'Makefile'`"
- then
- echo shar: error transmitting "'Makefile'" '(should have been 352 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'ien116.h'" '(393 characters)'
- if test -f 'ien116.h'
- then
- echo shar: will not over-write existing file "'ien116.h'"
- else
- sed 's/^X//' << \SHAR_EOF > 'ien116.h'
- X/* defines for the ien116 name server */
- X
- X#define PORT 42 /* Port for the server */
- X
- X/* Message types from IEN 116 */
- X#define ADDR_REQ 1 /* Address Request */
- X#define ADDR_ANS 2 /* Address Request Answer */
- X#define ERR 3 /* Error */
- X
- X/* Error types from IEN 116 */
- X#define UNK_ERR 0 /* Unknown Error */
- X#define HOST_UNK 1 /* Host Unknown */
- X#define SYNT_ERR 2 /* Syntax Error */
- SHAR_EOF
- if test 393 -ne "`wc -c < 'ien116.h'`"
- then
- echo shar: error transmitting "'ien116.h'" '(should have been 393 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'nameserver.c'" '(13854 characters)'
- if test -f 'nameserver.c'
- then
- echo shar: will not over-write existing file "'nameserver.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'nameserver.c'
- X#ifndef lint
- X static char *RCSid = "$Header: nameserver.c,v 2.3.1 88/02/26 jerry Rel $";
- X#endif
- X
- X/* nameserver --
- X Use the IEN 116 protocol to respond to nameserver requests.
- X
- X Modified by Jerry Aguirre. 21Mar1988
- X Count in header does not include header bytes. Added a "glob"
- X capability so "*" returns all host names. Removed fatal abort if no
- X tty so daemon can be started from rc.local.
- X
- X Written by Michael I. Bushnell.
- X Copyright (c) 1987 Michael I. Bushnell
- X You are hereby granted permission to use this program however you wish,
- X including copying and distribution. However, you are obligated not to sell
- X it or any part of it. Anyone who obtains this program receives the right
- X to do the same. This statement may not be removed from this program.
- X*/
- X
- X/*
- X * $Source: /u1/staff/mike/src/nameserver/RCS/nameserver.c,v $
- X * $Revision: 2.3 $
- X * $Date: 87/06/24 15:02:59 $
- X * $State: Rel $
- X * $Author: mike $
- X * $Locker: $
- X * $Log: nameserver.c,v $
- X * Revision 2.3.1 88/02/26 Jerry Aguirre
- X * Modified to work with Bridge terminal server version 1300. The field
- X * size doesn't include the 2 byte header. Also added a glob capability
- X * so '*' or 'xyz*' works. The '*' may not return all hosts because the
- X * sendto limits the size I can send.
- X *
- X * Revision 2.3 87/06/24 15:02:59 mike
- X * Final preparations for release. Addeed Copyright.
- X *
- X * Revision 2.2 87/06/24 14:54:29 mike
- X * de-lintified. Lint, stupidly, doesn't pick up the definition of h_errno f
- X * from libc.a. Sigh. Prepared for release.
- X *
- X * Revision 2.1 87/06/24 14:48:14 mike
- X * Better comments.
- X *
- X * Revision 2.0 87/06/23 16:55:03 mike
- X * Split it up into different functions.
- X *
- X * Revision 1.9 87/06/23 16:14:09 mike
- X * Added stuff to divorce process from shell and control terminal.
- X *
- X * Revision 1.8 87/06/19 16:59:36 mike
- X * Uses syslog instead of perror.
- X * Lots of symbolic constants.
- X *
- X * Revision 1.7 87/06/19 14:43:49 mike
- X * Fixed bug... need to initialize addrlen to sizeof(hisname).
- X *
- X * Revision 1.6 87/06/16 16:08:04 mike
- X * Changed all "sizeof (hisaddr)" to "addrlen."
- X * Still a bug...the last sendto is returning EINVAL???
- X *
- X * Revision 1.5 87/06/16 15:57:07 mike
- X * Actually...you need to return the raw bytes. So I changed it back.
- X * Also added bookoo error checking.
- X *
- X * Revision 1.4 87/06/15 13:50:22 mike
- X * Fixed bug...need to cast the argument of inet_ntoa into a struct in_addr.
- X *
- X * Revision 1.3 87/06/08 14:16:56 mike
- X * Uses a PORT number instead of system chosen default...now its 5001.
- X *
- X * Revision 1.2 87/06/08 14:10:33 mike
- X * Now it compiles.
- X *
- X * Revision 1.1 87/06/08 13:42:20 mike
- X * Initial revision
- X *
- X */
- X
- X#include <sys/file.h>
- X#include <sgtty.h>
- X
- X#include <signal.h>
- X#include <syslog.h>
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X#include "ien116.h"
- X
- X/* Generic constants */
- X#define BUFLEN 512 /* Length of I/O buffers */
- X#define RBUFLEN 1400 /* Length of glob reply buffer */
- X /* note that there is a limit on size of sendto */
- X#define DEF_PROTO 0 /* Use default protocol */
- X#define NO_FLAGS 0 /* No flags on recvfrom/sendto */
- X
- X/* Message lengths */
- X#define RET_MSG_LEN 6 /* Length of what we add to buf */
- X#define ERR_MSG_LEN 3 /* Length of error messages */
- X
- Xchar buf[BUFLEN]; /* Input/Output buffer */
- Xextern int errno, h_errno;
- Xextern char *sys_errlist[];
- X
- Xint debug;
- X
- Xmain(argc, argv) int argc; char *argv[];
- X{
- X int sock; /* Datagram socket */
- X struct sockaddr_in hisname; /* Address of requestor */
- X int addrlen; /* Length of his address */
- X struct hostent *hp, *gethostbyname(); /* Host inquired of */
- X char *name; /* Name of the machine requested */
- X int msglen; /* Length of the message received */
- X char *nameloc();
- X int arg, i;
- X
- X for (arg = 1; arg < argc; arg++) {
- X if (argv[arg][0] == '-') {
- X for (i = 1; argv[arg][i]; i++) {
- X switch (argv[arg][i]) {
- X case 'd':
- X if (isdigit(argv[arg][i+1])) {
- X debug = atoi(&argv[arg][i+1]);
- X break;
- X } else debug = 1;
- X continue;
- X
- X default:
- X fprintf(stderr, "nameserver: unknown option \'-%c\'.\n",
- X argv[arg][i]);
- X }
- X break;
- X }
- X } else {
- X fprintf(stderr, "nameserver: unexpected argument \"%s\".\n",
- X argv[arg]);
- X }
- X }
- X
- X if (!debug) setupsig(); /* Set up signal handling */
- X setuplog(); /* Set up the syslog connection */
- X if (!debug) divorce(); /* Divorce ourselves from terminal and shell */
- X sock = makesocket(); /* make and bind the socket */
- X
- X addrlen = sizeof(hisname);
- X
- X /* Main loop */
- X restart:
- X while (1)
- X {
- X /* Read a message */
- X msglen = recvfrom(sock, buf, BUFLEN - RET_MSG_LEN,
- X NO_FLAGS, (struct sockaddr *)&hisname, &addrlen);
- X if (debug) fprintf(stderr, "nameserver: got a request\n");
- X if (msglen == -1)
- X {
- X syslog(LOG_ERR, "Error on incoming message: %s\n",
- X sys_errlist[errno]);
- X if (debug) fprintf(stderr, "Error on incoming message: %s\n",
- X sys_errlist[errno]);
- X goto restart;
- X }
- X
- X /* Find the name */
- X name = nameloc(buf, BUFLEN, msglen, &hisname, addrlen, sock);
- X if ((int) name == -1) {
- X if (debug) fprintf(stderr, "nameserver: namelog() returned -1\n");
- X goto restart;
- X }
- X
- X if (isglob(name)) {
- X if (debug) fprintf(stderr, "nameserver: looking up pattern \"%s\".\n",
- X name);
- X doglob(name, &hisname, addrlen, sock);
- X goto restart;
- X }
- X
- X if (debug) fprintf(stderr, "nameserver: looking up host \"%s\".\n",
- X name);
- X /* Get the host entry */
- X if ((hp = gethostbyname(name))== NULL)
- X {
- X /* Send error message */
- X buf[msglen] = ERR;
- X buf[msglen+1] = ERR_MSG_LEN - 2;
- X if (h_errno == HOST_NOT_FOUND ||
- X h_errno == TRY_AGAIN ||
- X h_errno == NO_ADDRESS)
- X buf[msglen+2] = HOST_UNK;
- X else
- X buf[msglen+2] = UNK_ERR;
- X if (sendto(sock, buf, msglen+ERR_MSG_LEN, NO_FLAGS,
- X (struct sockaddr *)&hisname, addrlen)==-1)
- X {
- X syslog(LOG_ERR, "Error sending error 3: %s\n", sys_errlist[errno]);
- X goto restart;
- X }
- X }
- X else
- X {
- X /* Send the reply */
- X buf[msglen] = ADDR_ANS;
- X buf[msglen+1] = RET_MSG_LEN - 2;
- X buf[msglen+2] = hp->h_addr_list[0][0];
- X buf[msglen+3] = hp->h_addr_list[0][1];
- X buf[msglen+4] = hp->h_addr_list[0][2];
- X buf[msglen+5] = hp->h_addr_list[0][3];
- X
- X if (debug) fprintf(stderr, "nameserver: return IP %d.%d.%d.%d\n",
- X hp->h_addr_list[0][0] & 0xff,
- X hp->h_addr_list[0][1] & 0xff,
- X hp->h_addr_list[0][2] & 0xff,
- X hp->h_addr_list[0][3] & 0xff);
- X
- X if (sendto(sock, buf, msglen+RET_MSG_LEN, NO_FLAGS,
- X (struct sockaddr *)&hisname, addrlen)==-1)
- X {
- X syslog(LOG_ERR, "Error sending reply: %s\n", sys_errlist[errno]);
- X goto restart;
- X }
- X }
- X }
- X}
- X
- X
- X/* setupsig -- Set all signals to be ignored. Those which cannot be ignored
- X will be left at the default. */
- Xsetupsig()
- X{
- X int i; /* Index of signals */
- X
- X for (i=0; i < NSIG; ++i)
- X (void) signal(i, SIG_IGN);
- X}
- X
- X
- X/* setuplog -- set up the syslog connection */
- Xsetuplog()
- X{
- X openlog("nameserver", LOG_PID | LOG_CONS, LOG_DAEMON);
- X}
- X
- X
- X/* divorce -- Divorce ourselves from the terminal and the shell */
- Xdivorce()
- X{
- X int term; /* Terminal filed */
- X
- X /* First the shell */
- X switch(fork())
- X {
- X case -1:
- X syslog(LOG_CRIT, "Cannot fork: %s\n", sys_errlist[errno]);
- X exit(1);
- X break;
- X case 0:
- X break;
- X default:
- X exit(0);
- X break;
- X }
- X
- X /* Now the files */
- X /* POTENTIAL BUG-- ASSUMES THAT THE TERMINAL IS ONLY OPEN ON FILEDS 0,1,2 */
- X (void) close (0);
- X (void) close (1);
- X (void) close (2);
- X /* Now the terminal */
- X /* if started from rc.local, crontab, etc. there is no tty */
- X if ((term = open("/dev/tty", O_RDWR, 0)) >= 0)
- X {
- X if (ioctl(term, TIOCNOTTY, (char *) 0) == -1)
- X {
- X syslog(LOG_CRIT, "Cannot divorce from control terminal: %s\n",
- X sys_errlist[errno]);
- X exit(1);
- X }
- X (void) close(term);
- X }
- X}
- X
- X
- X/* makesocket -- return the filed of a new bound socket */
- Xmakesocket()
- X{
- X int sock; /* Socket */
- X struct sockaddr_in ourname; /* Our name */
- X
- X /* create the socket */
- X sock = socket(AF_INET, SOCK_DGRAM, DEF_PROTO);
- X if (sock < 0)
- X {
- X syslog(LOG_CRIT, "Error opening socket: %s\n", sys_errlist[errno]);
- X exit(1);
- X }
- X ourname.sin_family = AF_INET;
- X ourname.sin_port = htons((u_short)PORT);
- X ourname.sin_addr.s_addr = INADDR_ANY;
- X if (bind(sock, &ourname, sizeof(ourname)))
- X
- X {
- X syslog(LOG_CRIT, "Error binding socket: %s\n", sys_errlist[errno]);
- X exit(1);
- X }
- X return sock;
- X}
- X
- X
- X/* nameloc -- return the address of a null-terminated string which is the
- X name to be looked up. Report syntax errors to reportto through sock.
- X If an error occurs, return (char *) -1. If an error occurs, buf will be
- X changed. */
- Xchar *
- Xnameloc(buf, buflen, msglen, reportto, addrlen, sock)
- X char *buf; /* Buffer holding the request */
- X int buflen, /* Length of the buffer */
- X msglen, /* Length of the message in the buffer */
- X sock, /* Socket for error replies */
- X addrlen; /* Length of reportto */
- X struct sockaddr_in *reportto; /* Who we report errors to */
- X{
- X char *name; /* Address of the name */
- X int code; /* Type of request */
- X
- X buf[msglen] = '\0';
- X /* Check type */
- X code = buf[0];
- X if (code != ADDR_REQ)
- X if (code !=ADDR_ANS && code !=ERR)
- X {
- X /* Send error message */
- X buf[0] = ERR;
- X buf[1] = ERR_MSG_LEN - 2;
- X buf[2] = SYNT_ERR;
- X if (sendto(sock, buf, ERR_MSG_LEN, NO_FLAGS,
- X (struct sockaddr *)&reportto, addrlen)==-1)
- X {
- X syslog(LOG_ERR, "Error sending error 0: %s\n", sys_errlist[errno]);
- X return (char *) -1;
- X }
- X }
- X else
- X return (char *) -1;
- X
- X /* Put name at the start of a null-terminated string */
- X if (buf[2]!='!')
- X name=buf+2;
- X else
- X {
- X for(name=buf+2; *name!='!'; ++name)
- X if (name-buf >= buflen)
- X {
- X /* Send error packet */
- X buf[0] = ERR;
- X buf[1] = ERR_MSG_LEN - 2;
- X buf[2] = SYNT_ERR;
- X if (sendto(sock, buf, ERR_MSG_LEN, NO_FLAGS,
- X (struct sockaddr *)&reportto, addrlen)==-1)
- X {
- X syslog(LOG_ERR, "Error sending error 1: %s\n",
- X sys_errlist[errno]);
- X return (char *) -1;
- X }
- X }
- X for(++name; *name!='!'; ++name)
- X if (name-buf >= buflen)
- X {
- X /* Send error packet */
- X buf[0] = ERR;
- X buf[1] = ERR_MSG_LEN - 2;
- X buf[2] = SYNT_ERR;
- X if (sendto(sock, buf, ERR_MSG_LEN, NO_FLAGS,
- X (struct sockaddr *)&reportto, addrlen)==-1)
- X {
- X syslog(LOG_ERR, "Error sending error 2: %s\n",
- X sys_errlist[errno]);
- X return (char *) -1;
- X }
- X }
- X ++name;
- X }
- X return name;
- X}
- X
- Xint
- Xisglob(s) char *s; /* true if string s has pattern characters */
- X{
- X while (*s) {
- X switch (*s++) {
- X case '*': return 1;
- X }
- X }
- X return 0;
- X}
- X
- X/* check all hosts against pattern 's'. To reduce clutter only the
- X * primary host name is checked, aliases are ignored.
- X */
- Xdoglob(s, reportto, addrlen, sock)
- X char *s; /* string containing pattern */
- X struct sockaddr_in *reportto; /* Who we report errors to */
- X int addrlen; /* Length of reportto */
- X int sock; /* Socket for error replies */
- X{
- X struct hostent *hp, *gethostent();
- X int i, l, n;
- X char buf[RBUFLEN]; /* Output buffer */
- X
- X if (s[0] == '\0') { /* null pattern is illegal */
- X reterror(ADDR_REQ, s, SYNT_ERR, reportto, addrlen, sock);
- X return 0;
- X }
- X sethostent(1);
- X i = 0; n = 0;
- X while ((i < RBUFLEN) && (hp = gethostent())) {
- X if (requ(s, hp->h_name)) { /* we found a match */
- X n++;
- X l = strlen(hp->h_name);
- X if (l > 255) l = 255;
- X if ((i + 2 + l + 2 + 4) >= RBUFLEN) break;
- X buf[i++] = ADDR_REQ;
- X buf[i++] = l;
- X strncpy(buf+i, hp->h_name, l);
- X i += l;
- X buf[i++] = ADDR_ANS;
- X buf[i++] = 4;
- X buf[i++] = hp->h_addr_list[0][0];
- X buf[i++] = hp->h_addr_list[0][1];
- X buf[i++] = hp->h_addr_list[0][2];
- X buf[i++] = hp->h_addr_list[0][3];
- X }
- X }
- X endhostent();
- X if (n == 0) {
- X reterror(ADDR_REQ, s, HOST_UNK, reportto, addrlen, sock);
- X return 1;
- X }
- X if (i > 0) {
- X if (sendto(sock, buf, i, NO_FLAGS,
- X (struct sockaddr *)reportto, addrlen)==-1) {
- X syslog(LOG_ERR, "Error sending reply: %s\n", sys_errlist[errno]);
- X return 0;
- X }
- X }
- X return 1;
- X}
- X
- Xreterror(rcode, rs, ecode, reportto, addrlen, sock)
- X int rcode; /* type of request containing error */
- X char *rs; /* string for above request */
- X int ecode; /* error code to return */
- X struct sockaddr_in *reportto; /* Who we report errors to */
- X int addrlen; /* Length of reportto */
- X int sock; /* Socket for error replies */
- X{
- X int i;
- X char buf[BUFLEN]; /* Output buffer */
- X
- X buf[0] = rcode;
- X i = strlen(rs);
- X if (i > 255) i = 255;
- X buf[1] = i;
- X strncpy(buf+2, rs, i);
- X i += 2;
- X buf[i++] = ERR;
- X buf[i++] = 1;
- X buf[i++] = ecode;
- X if (sendto(sock, buf, i, NO_FLAGS,
- X (struct sockaddr *)&reportto, addrlen)==-1) {
- X syslog(LOG_ERR, "Error sending error %d: %s\n",
- X ecode, sys_errlist[errno]);
- X return 0;
- X }
- X return 1;
- X}
- X
- X/* Compare pattern 'p' to string 's'. Pattern can contain '*'
- X * characters that will match 0 or more characters in string. Otherwise
- X * the strings are compared on a character by character basis. Returns
- X * non-zero for a match.
- X */
- Xint
- Xrequ(p, s) register char *p, *s;
- X{
- X while (*p) {
- X if (*p == '*') {
- X do {
- X if (requ(p+1, s)) return 1; /* match */
- X } while (*s++);
- X return 0; /* no match */
- X }
- X else if (*s == '\0') return 0; /* no match */
- X else if (*p != *s) return 0; /* no match */
- X p++; s++; /* they match so far */
- X }
- X if (*s) return 0; /* no match */
- X return 1; /* reached end of both strings, match */
- X}
- SHAR_EOF
- if test 13854 -ne "`wc -c < 'nameserver.c'`"
- then
- echo shar: error transmitting "'nameserver.c'" '(should have been 13854 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'driver.c'" '(4768 characters)'
- if test -f 'driver.c'
- then
- echo shar: will not over-write existing file "'driver.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'driver.c'
- X#ifndef lint
- X static char *RCSid = "$Header: driver.c,v 1.5.1 88/02/26 jerry Rel $";
- X#endif
- X
- X/* driver --
- X drive the IEN 116 nameserver.
- X
- X Modified by Jerry Aguirre. 21Mar1988
- X First argument is name of server to use. Other arguments are names
- X to find. More extensive display of responses.
- X
- X Written by Michael I. Bushnell.
- X Copyright (c) 1987 Michael I. Bushnell
- X You are hereby granted permission to use this program however you wish,
- X including copying and distribution. However, you are obligated not to sell
- X it or any part of it. Anyone who obtains this program receives the right
- X to do the same. This statement may not be removed from this program.
- X*/
- X
- X/*
- X * $Source: /u1/staff/mike/src/nameserver/RCS/driver.c,v $
- X * $Revision: 1.5 $
- X * $Date: 87/06/24 15:02:38 $
- X * $State: Rel $
- X * $Author: mike $
- X * $Locker: $
- X * $Log: driver.c,v $
- X * Revision 1.5.1 88/02/26 Jerry Aguirre <jerry@olivetti.com>
- X * Field sizes don't include 2 byte header. First arg is now name
- X * of server to request from. Structure of response message is displayed.
- X *
- X * Revision 1.5 87/06/24 15:02:38 mike
- X * Prepared for final release. Added Copyright.
- X *
- X * Revision 1.4 87/06/19 17:00:05 mike
- X * More toying around.
- X *
- X * Revision 1.3 87/06/19 14:44:13 mike
- X * Toyed around.
- X *
- X * Revision 1.2 87/06/15 13:50:51 mike
- X * Changed the host it asks for
- X *
- X * Revision 1.1 87/06/12 13:42:29 mike
- X * Initial revision
- X *
- X */
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <stdio.h>
- X#include <netdb.h>
- X
- X#include "ien116.h"
- X
- X#define BUFLEN 2000
- Xchar buf[BUFLEN];
- X
- X/* Driver for the IEN 116 nameserver */
- X
- Xmain(argc, argv) int argc; char *argv[];
- X{
- X int sock; /* Datagram socket */
- X struct sockaddr_in from; /* Where we got the reply from */
- X struct sockaddr_in server; /* Server's address */
- X struct sockaddr_in ourname; /* Our address */
- X int addrlen; /* Address length */
- X int c,i; /* Generic counters */
- X int arg;
- X struct hostent *hp, *gethostbyname(); /* Host inquired of */
- X char *hostname;
- X int j, k;
- X int code, length;
- X
- X if (argc < 3) {
- X printf("usage: driver server name ...");
- X exit(1);
- X }
- X
- X sock = socket(AF_INET, SOCK_DGRAM, 0);
- X if (sock < 0)
- X {
- X perror("driver: opening socket");
- X exit (1);
- X }
- X ourname.sin_family = AF_INET;
- X ourname.sin_port = 0;
- X ourname.sin_addr.s_addr = INADDR_ANY;
- X if (bind(sock, (struct sockaddr *)&ourname, sizeof(ourname)))
- X {
- X perror("driver: binding socket");
- X exit(1);
- X }
- X
- X /* server.sin_family = AF_INET; */
- X server.sin_port = htons((u_short)PORT);
- X /* server.sin_addr.s_addr = INADDR_ANY; */
- X server.sin_addr.s_addr = INADDR_ANY;
- X hp = gethostbyname(argv[1]);
- X if (hp) {
- X server.sin_family = hp->h_addrtype;
- X#ifndef NOT43
- X bcopy(hp->h_addr_list[0], (caddr_t)&server.sin_addr,
- X hp->h_length);
- X#else NOT43
- X bcopy(hp->h_addr, (caddr_t)&server.sin_addr,
- X hp->h_length);
- X#endif NOT43
- X hostname = hp->h_name;
- X } else {
- X printf("%s: unknown host\n", argv[1]);
- X exit(1);
- X }
- X
- X for (arg = 2; arg < argc; arg++) {
- X i = strlen(argv[arg]);
- X buf[0] = ADDR_REQ; /* Code for request */
- X buf[1] = i; /* Length of message */
- X strcpy(buf+2, argv[arg]); /* name */
- X
- X if (sendto(sock, buf, i+2, 0, (struct sockaddr *)&server, sizeof(server))==-1)
- X {
- X perror("driver: sending message");
- X exit(1);
- X }
- X
- X if ((c=recvfrom(sock, buf, BUFLEN, 0, (struct sockaddr *)&from, sizeof(from)))==-1)
- X {
- X perror("driver: getting message");
- X exit(1);
- X }
- X
- X printf("response for \"%s\" (%d bytes):\n", argv[arg], c);
- X for(i=0;(i + 1) <c;) {
- X putchar('\t');
- X code = buf[i++] & 0xff;
- X length = buf[i++] & 0xff;
- X switch (code) {
- X case ADDR_REQ:
- X printf("ADDR_REQ: length %d \"", length);
- X for (k = 0; k < length; k++) {
- X if ((buf[i+k] >= ' ') && (buf[i+k] <= '~')) putchar(buf[i+k]);
- X else printf("\\%3.3o", buf[i+k] & 0xff);
- X }
- X printf("\"");
- X break;
- X case ADDR_ANS:
- X printf("ADDR_ANS: length %d", length);
- X for (k = 0; k < length; k++) {
- X if (k == 0) printf(" %d", buf[i+k] & 0xff);
- X else printf(".%d", buf[i+k] & 0xff);
- X }
- X break;
- X case ERR:
- X printf("ERR: length %d", length);
- X for (k = 0; k < length; k++) {
- X j = buf[i+k] & 0xff;
- X printf(" error code %d", j);
- X switch (j) {
- X case UNK_ERR:
- X printf(" UNK_ERR");
- X break;
- X case HOST_UNK:
- X printf(" HOST_UNK");
- X break;
- X case SYNT_ERR:
- X printf(" SYNT_ERR");
- X break;
- X default:
- X printf("????");
- X }
- X }
- X break;
- X default:
- X printf("Unknown response code 0x%x, length %d.", buf[i] & 0xff, length);
- X break;
- X }
- X i += length;
- X printf("\n");
- X }
- X } /* for each arg */
- X}
- SHAR_EOF
- if test 4768 -ne "`wc -c < 'driver.c'`"
- then
- echo shar: error transmitting "'driver.c'" '(should have been 4768 characters)'
- fi
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-